package com.dsg.service.oil.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dsg.common.constants.DsgStatusConstant;
import com.dsg.common.security.SystemAuthorizingUser;
import com.dsg.common.util.DateUtils;
import com.dsg.common.util.SingletonLoginUtils;
import com.dsg.common.util.UUIDGenerator;
import com.dsg.common.util.toolbox.CollectionUtil;
import com.dsg.dao.oil.DsgOilDataDetailMapper;
import com.dsg.dao.oil.DsgOilDataMapper;
import com.dsg.entity.account.DsgAccountTrade;
import com.dsg.entity.bank.DsgBankDetail;
import com.dsg.entity.dto.DsgOilDataDetailDto;
import com.dsg.entity.dto.DsgOilDataDetailTwoCreditCardDto;
import com.dsg.entity.dto.DsgOilDataDetailTwoDto;
import com.dsg.entity.dto.RecentOilDto;
import com.dsg.entity.oil.DsgOilData;
import com.dsg.entity.oil.DsgOilDataDetail;
import com.dsg.entity.oil.DsgOilDataText;
import com.dsg.entity.system.DsgSysFile;
import com.dsg.service.DsgServiceImpl;
import com.dsg.service.oil.IDsgOilDataDetailService;
import com.dsg.service.oil.IDsgOilDataTextService;
import com.dsg.service.oil.IDsgOilProductService;
import com.dsg.service.system.IDsgSysFileService;
import com.dsg.util.ExcelIteratorReader;
import com.dsg.util.RRException;
import com.dsg.util.verify.VerifyHolder;
import com.dsg.util.verify.impl.NotEmptyVerify;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 入油数据明细 服务实现类
 * </p>
 *
 * @author system
 * @since 2020-07-02
 */
@Service
public class DsgOilDataDetailServiceImpl extends DsgServiceImpl<DsgOilDataDetailMapper, DsgOilDataDetail> implements IDsgOilDataDetailService {
    @Autowired
    private DsgOilDataDetailMapper dsgOilDataDetailMapper;
    @Autowired
    private DsgOilDataMapper dsgOilDataMapper;
    @Autowired
    private IDsgOilDataTextService dsgOilDataTextService;
    @Autowired
    private IDsgSysFileService dsgSysFileService;
    @Autowired
    private IDsgOilProductService dsgOilProductService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importExcel(File file, DsgOilData dsgOilData) throws Exception {
        dsgOilData.setEntCode(SingletonLoginUtils.getSystemEntCode());
        //錯誤信息
        List<String> errorList = new ArrayList<>();
        ExcelIteratorReader excelIteratorReader;
        VerifyHolder verifyHolder;
        //讀取Excel
        switch (dsgOilData.getEntCode()) {
            case "PDL":
                //PDL (現金卡和記賬卡格式不一樣)
                //現金卡
                if (dsgOilData.getDataType().intValue() == 1) {
                    excelIteratorReader = new ExcelIteratorReader(file, DsgOilDataDetailTwoDto.class, 0, 0, errorList);
                    verifyHolder = new VerifyHolder(DsgOilDataDetailTwoDto.class, errorList);
                } else {
                    //記賬卡
                    excelIteratorReader = new ExcelIteratorReader(file, DsgOilDataDetailTwoCreditCardDto.class, 0, 0, errorList);
                    verifyHolder = new VerifyHolder(DsgOilDataDetailTwoCreditCardDto.class, errorList);
                }
                verifyHolder.addVerify(new NotEmptyVerify());
                break;
            default:
                //默認HB HBC (現金卡和記賬卡格式一樣)
                excelIteratorReader = new ExcelIteratorReader(file, DsgOilDataDetailDto.class, 0, 0, errorList);
                verifyHolder = new VerifyHolder(DsgOilDataDetailDto.class, errorList);
                verifyHolder.addVerify(new NotEmptyVerify());
                break;
        }
        Iterator iterator = excelIteratorReader.iterator();
        //導入數據集合
        List<DsgOilDataDetail> dsgOilDataDetailList = new ArrayList<>();
        List<DsgOilDataText> dsgOilDataTextList = new ArrayList<>();
        int row = 1;
        if (iterator.hasNext()) {
            //入油匯總表ID
            dsgOilData.setOid(UUIDGenerator.getUUID());
            BigDecimal sumOilLiters = BigDecimal.ZERO;
            BigDecimal sumOilValue = BigDecimal.ZERO;
            while (iterator.hasNext()) {
                row++;
                DsgOilDataDetail dsgOilDataDetail = new DsgOilDataDetail();
                switch (dsgOilData.getEntCode()) {
                    case "HB":
                    case "HBC":
                        DsgOilDataDetailDto dsgOilDataDetailDto = (DsgOilDataDetailDto) iterator.next();
                        //數據校驗
                        verifyHolder.check(dsgOilDataDetailDto, row);
                        BeanUtils.copyProperties(dsgOilDataDetailDto, dsgOilDataDetail);
                        //計算公式為：入油升數 * 入油時間的牌價
                        dsgOilDataDetail.setOilValue(dsgOilDataDetail.getOilLiters().multiply(dsgOilDataDetail.getOilPrice()));
                        break;
                    case "PDL":
                        //現金卡
                        if (dsgOilData.getDataType().intValue() == 1) {
                            DsgOilDataDetailTwoDto dsgOilDataDetailTwoDto = (DsgOilDataDetailTwoDto) iterator.next();
                            //實例數據校驗
                            verifyHolder.check(dsgOilDataDetailTwoDto, row);
                            BeanUtils.copyProperties(dsgOilDataDetailTwoDto, dsgOilDataDetail);
                            dsgOilDataDetail.setOilPrice(dsgOilDataDetail.getOilValue().divide(dsgOilDataDetail.getOilLiters(), 4, BigDecimal.ROUND_HALF_UP));
                        } else {
                            DsgOilDataDetailTwoCreditCardDto dsgOilDataDetailTwoCreditCardDto = (DsgOilDataDetailTwoCreditCardDto) iterator.next();
                            //實例數據校驗
                            verifyHolder.check(dsgOilDataDetailTwoCreditCardDto, row);
                            BeanUtils.copyProperties(dsgOilDataDetailTwoCreditCardDto, dsgOilDataDetail);
                        }
                        break;
                }
                //處理數據
                dsgOilDataDetail.setOid(UUIDGenerator.getUUID());
                dsgOilDataDetail.setPid(dsgOilData.getOid());
                dsgOilDataDetail.setDiscount(BigDecimal.ZERO);
                sumOilLiters = sumOilLiters.add(dsgOilDataDetail.getOilLiters());
                sumOilValue = sumOilValue.add(dsgOilDataDetail.getOilValue());
                //是否接受
                dsgOilDataDetail.setIsAccept(DsgStatusConstant.IS_ACCEPT_ZERO);
                //是否成功
                dsgOilDataDetail.setIsSuccess(DsgStatusConstant.IS_ACCEPT_ZERO);
                //是否记入交易账目
                dsgOilDataDetail.setIsAccount(DsgOilDataDetail.AppStatus.notCredit.getCode());
                dsgOilDataDetailList.add(dsgOilDataDetail);
                //入油数据文本
                DsgOilDataText dsgOilDataText = new DsgOilDataText();
                dsgOilDataText.setOid(UUIDGenerator.getUUID());
                dsgOilDataText.setPid(dsgOilDataDetail.getOid());
                dsgOilDataText.setJsonData(JSONObject.toJSONString(dsgOilDataDetail));
                dsgOilDataTextList.add(dsgOilDataText);
                JSONObject.toJSONString(dsgOilDataDetail);
            }
            if (CollectionUtil.isNotEmpty(errorList)) {
                throw new RRException(errorList.toString());
            } else {
                //匯總入油數據
//                dsgOilData.setDataType(1);//資料類型
                //批次號
                dsgOilData.setBatchNo(DateUtils.getStringDate());
                //入油總升數
                dsgOilData.setTotalRise(sumOilLiters);
                //總金額
                dsgOilData.setTotolAmount(sumOilValue);
                //檢測狀態
                dsgOilData.setCheckStatus(DsgStatusConstant.IS_DEFAULT_ZERO);
                //處理狀態
                dsgOilData.setHandleStatus(DsgStatusConstant.IS_DEFAULT_ZERO);
                //上載數量
                dsgOilData.setUploadNum(new BigDecimal(dsgOilDataDetailList.size()));
                //拒絕數量
                dsgOilData.setRefuseNum(BigDecimal.ZERO);
                //接受數量
                dsgOilData.setAcceptNum(BigDecimal.ZERO);
                //成功數量
                dsgOilData.setSuccessNum(BigDecimal.ZERO);
                //失敗數量
                dsgOilData.setFailNum(BigDecimal.ZERO);
                //存疑A數量
                dsgOilData.setDoubtANum(BigDecimal.ZERO);
                //存疑B數量
                dsgOilData.setDoubtBNum(BigDecimal.ZERO);
                //存疑C數量
                dsgOilData.setDoubtCNum(BigDecimal.ZERO);
                dsgOilDataMapper.insert(dsgOilData);
                //批量更新
                saveBatch(dsgOilDataDetailList);
                dsgOilDataTextService.saveBatch(dsgOilDataTextList);
                //保存文件
                dsgSysFileService.saveFile(new DsgSysFile(), file, dsgOilData.getOid(), "xlsx");
            }
        } else {
            throw new RRException("文件數據為空！");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateIsAccept(String idList, String isAccept) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("OID", Arrays.asList(idList.split(",")));
        List<DsgOilDataDetail> dsgOilDataDetailList = dsgOilDataDetailMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(dsgOilDataDetailList)) {
            Date date = new Date();
            SystemAuthorizingUser sysUser = SingletonLoginUtils.getSystemUser();
            dsgOilDataDetailList.forEach(I -> {
                I.setIsAccept(Integer.parseInt(isAccept));
                I.setUpdater(sysUser.getUserId());
                I.setUpdateTime(date);
            });
            String pid = dsgOilDataDetailList.get(0).getPid();
            //批量更新
            updateBatchById(dsgOilDataDetailList);
            DsgOilData dsgOilData = dsgOilDataMapper.selectById(pid);
            queryWrapper = new QueryWrapper();
            queryWrapper.select("IS_ACCEPT as isAccept,count(0) as iCount");
            queryWrapper.eq("PID", pid);
            queryWrapper.groupBy("IS_ACCEPT");
            List<Map<String, Number>> dsgOilDataDetailMap = dsgOilDataDetailMapper.selectMaps(queryWrapper);
            dsgOilDataDetailMap.forEach(I -> {
                if (I.get("isAccept").equals(DsgStatusConstant.IS_ACCEPT_ONE)) {
                    dsgOilData.setAcceptNum(new BigDecimal(I.get("iCount").intValue()));
                } else {
                    if (I.get("isAccept").equals(DsgStatusConstant.IS_ACCEPT_TOW)) {
                        dsgOilData.setRefuseNum(new BigDecimal(I.get("iCount").intValue()));
                    }
                }
            });
            dsgOilData.setUpdater(sysUser.getUserId());
            dsgOilData.setUpdateTime(date);
            //更新入油匯總數量
            dsgOilDataMapper.updateById(dsgOilData);
        } else {
            throw new RRException("入油明細數據不存在！");
        }
    }

    @Override
    public List<DsgOilDataDetail> selectDsgBankOilDataDetail(DsgBankDetail dsgBankDetail) {
        return dsgOilDataDetailMapper.selectDsgBankOilDataDetail(dsgBankDetail);
    }

    @Override
    public List<DsgOilDataDetail> selectRepeatList(DsgOilDataDetail dsgOilDataDetail) {
        return dsgOilDataDetailMapper.selectRepeatList(dsgOilDataDetail);
    }

    @Override
    public Integer selectByCar(String carNo) {
        return baseMapper.selectByCar(carNo);
    }

    @Override
    public List<RecentOilDto> selectRecent(String ownsId, String carNo) {
        return baseMapper.selectRecent(ownsId, carNo);
    }

    @Override
    public Page selectListAdj(Page page, DsgAccountTrade dsgAccountTrade) {
        return page.setRecords(dsgOilDataDetailMapper.selectListAdj(page, dsgAccountTrade));
    }
}